Write a custom CUDA kernel to replace PyTorch's InstanceNorm + Dropout implementation for CNN layers.

You are given the following PyTorch architecture:

python
import torch
import torch.nn as nn

class Model(nn.Module):
"""
Simple model that performs InstanceNorm + Dropout.
"""
def init(self, num_features=64, eps=1e-5, affine=True, dropout_p=0.1, track_running_stats=False):
super(Model, self).init()
self.instance_norm = nn.InstanceNorm2d(
    num_features=num_features,
    eps=eps,
    affine=affine,
    track_running_stats=track_running_stats
)
self.dropout = nn.Dropout(p=dropout_p)

def forward(self, x: torch.Tensor) -> torch.Tensor:  
    """  
    Applies InstanceNorm to the input tensor and then applies dropout.  

    Args:  
        x (torch.Tensor): Input tensor of shape [B, C, H, W].  

    Returns:  
        torch.Tensor: Dropout(InstanceNorm(x)), same shape as input.  
    """  
    x_normalized = self.instance_norm(x)
    return self.dropout(x_normalized)

batch_size = 32
num_features = 64
height = 128
width = 128

def get_inputs():
x = torch.randn(batch_size, num_features, height, width)
return [x]

def get_init_inputs():
return [num_features]


Your task is to optimize this InstanceNorm + Dropout implementation by:

1. **Operator Fusion**: Combine InstanceNorm computation (mean, variance, normalization) and Dropout masking into a single CUDA kernel to eliminate intermediate tensor storage and reduce memory bandwidth overhead.

2. **Memory Access Optimization**: Minimize global memory access by keeping intermediate computations in registers, and ensure coalesced memory access patterns for the [B, C, H, W] tensor layout.

3. **Shared Memory Optimization**: Use shared memory for efficient parallel reduction when computing mean and variance across spatial dimensions (H*W) within each instance and channel.

4. **Dropout Mask Integration**: Implement dropout masking directly within the kernel to avoid separate mask generation and application steps, ensuring consistent random number generation with PyTorch's dropout behavior.

5. **Training/Inference Modes**: Support both training mode (with dropout) and inference mode (without dropout) for optimal performance in different scenarios.

6. **Thread Configuration**: Use optimal block size (e.g., 256 threads) and compute grid dimensions based on batch_size and num_features to maximize GPU utilization.

7. **Numerical Stability**: Ensure proper epsilon handling in InstanceNorm computation to avoid division by zero and maintain numerical precision.

The optimized CUDA kernel should:
- Take input tensor x, weight, and bias as input (all float32)
- Compute InstanceNorm (mean, variance, normalization) and apply dropout in a single kernel
- Support both training and inference modes
- Handle dropout probability scaling correctly (1/(1-p) for retained elements)
- Use shared memory for efficient mean and variance computation
- Maintain numerical stability with proper epsilon handling
- Achieve significant speedup over PyTorch's separate InstanceNorm + Dropout implementation
- Support both affine and non-affine modes
- Ensure dropout behavior is consistent with PyTorch's implementation

Follow the inline CUDA extension syntax example provided in reference. The kernel should be optimized for GPU architectures and demonstrate performance improvements through reduced memory access, fused computation, and efficient parallel reduction.
